#ifndef RANDOM32
#define RANDOM32

#include < time.h>
#include < stdio.h>

long random();

#define TYPE_3    3   // x**31 + x**3 + 1
#define BREAK_3   128
#define DEG_3     31
#define SEP_3     3

static long randtbl[DEG_3 + 1] = 
{
	TYPE_3,
	0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
	0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
	0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
	0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
	0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
	0xf3bec5da
};



static long *fptr = &randtbl[SEP_3 + 1];
static long *rptr = &randtbl[1];


static long *state = &randtbl[1];
static long rand_type = TYPE_3;
static long rand_deg = DEG_3;
static long rand_sep = SEP_3;
static long *end_ptr = &randtbl[DEG_3 + 1];

__inline static long good_rand(long x)
{
	long hi, lo;

	// Can't be initialized with 0, so use another value.
	if (x == 0)
		x = 123459876;
	hi = x / 127773;
	lo = x % 127773;
	x = 16807 * lo - 2836 * hi;
	if (x < 0)
		x += 0x7fffffff;
	return x;
}


void srandom(unsigned long x)
{
	long i, lim;

	state[0] = x;

	for (i = 1; i < rand_deg; i++)
		state[i] = good_rand(state[i - 1]);
	fptr = &state[rand_sep];
	rptr = &state[0];
	lim = 10 * rand_deg;


	for (i = 0; i < lim; i++)
		random();
}


long random()
{
	long i;
	long *f, *r;


	f = fptr;
	r = rptr;
	*f += *r;
	i = (*f >> 1) & 0x7fffffff; // Chucking least random bit
	if (++f >= end_ptr) 
	{
		f = state;
		++r;
	}
	else if (++r >= end_ptr) 
		r = state;

	fptr = f;
	rptr = r;


	return i;
}
#endif